package com.chixing.service.impl;



import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;


import com.chixing.entity.MovieDetail;
import com.chixing.mapper.MovieDetailMapper;
import com.chixing.service.IMovieDetailService;

import com.chixing.util.Result;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author liwenjing
 * @since 2025-10-07
 */
@Service
public class MovieDetailServiceImpl implements IMovieDetailService {
    @Autowired
    private ElasticsearchClient elasticsearchClient;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private MovieDetailMapper movieDetailMapper;
    /**
     * 将MySQL中Product的数据保存到Elasticsearch
     * */
    @Override
    public Result saveMoviesElasticSearch() {
        QueryWrapper<MovieDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("movie_detail_id", "movie_name", "movie_intro",
                "movie_type", "director", "actors", "box_office", "score", "release_time","movie_image");

        List<MovieDetail> movieList = movieDetailMapper.selectList(queryWrapper);
        System.out.println("查询到的电影数量：" + movieList.size());

        // 保存到 Elasticsearch
        elasticsearchTemplate.save(movieList);
        System.out.println("已将电影数据同步到 Elasticsearch！");
        return  Result.getSuccess(movieList);
    }
    /**
     * 根据关键字搜索
     * @param keyword
     * @return
     */
    @Override
    public List<MovieDetail> getByKeyword(String keyword) {
        List<MovieDetail> movieList = new ArrayList<>();

        try {
            SearchResponse<MovieDetail> response = elasticsearchClient.search(s -> s
                            .index("movie_detail")
                            .query(q -> q
                                    .multiMatch(m -> m
                                            .query(keyword)
                                            .fields("movieName", "movieIntro", "movieType", "director", "actors","movieImage")
                                    )
                            ),
                    MovieDetail.class
            );

            List<Hit<MovieDetail>> hits = response.hits().hits();
            for (Hit<MovieDetail> hit : hits) {
                movieList.add(hit.source());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return movieList;
    }
    /**
     * 分词高亮查询，  分页与根据电影票房box_office升序排序
     * @param keyword
     * @return
     */
    @Override
    public List<MovieDetail> getByKeywordAndPageWithBoxOffice(String keyword, Integer page) {
        List<MovieDetail> movieList = new ArrayList<>();

        try {
            SearchResponse<MovieDetail> response = elasticsearchClient.search(s -> s
                            .index("movie_detail")
                            .query(q -> q
                                    .multiMatch(m -> m
                                            .query(keyword)
                                            .fields("movieName", "movieIntro", "movieType", "director", "actors")
                                    )
                            )
                            .from((page - 1) * 5) // 每页5条
                            .size(5)
                            .sort(sort -> sort
                                    .field(f -> f
                                            .field("boxOffice") // ✅ 按票房排序
                                            .order(SortOrder.Asc)
                                    )
                            )
                            .highlight(h -> h
                                    .fields("movieName", f -> f
                                            .preTags("<em style='color:red'>")
                                            .postTags("</em>")
                                    )
                                    .fields("movieIntro", f -> f
                                            .preTags("<em style='color:red'>")
                                            .postTags("</em>")
                                    )
                                    .fields("actors", f -> f
                                            .preTags("<em style='color:red'>")
                                            .postTags("</em>")
                                    )
                                    .fields("director", f -> f
                                            .preTags("<em style='color:red'>")
                                            .postTags("</em>")
                                    )
                            ),
                    MovieDetail.class
            );

            if (response != null) {
                List<Hit<MovieDetail>> hits = response.hits().hits();
                for (Hit<MovieDetail> hit : hits) {
                    MovieDetail movie = hit.source();

                    if (movie != null) {
                        Map<String, List<String>> highlight = hit.highlight();
                        if (highlight != null) {
                            if (highlight.containsKey("movieName")) {
                                movie.setMovieName(String.join("", highlight.get("movieName")));
                            }
                            if (highlight.containsKey("movieIntro")) {
                                movie.setMovieIntro(String.join("", highlight.get("movieIntro")));
                            }
                            if (highlight.containsKey("actors")) {
                                movie.setActors(String.join("", highlight.get("actors")));
                            }
                            if (highlight.containsKey("director")) {
                                movie.setDirector(String.join("", highlight.get("director")));
                            }
                        }
                        movieList.add(movie);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return movieList;
    }
}
